package view;

import game.test.EightQueensSimulatorTileInfo;
import game.test.EightQueensTestSimulatorBuilder;

import java.util.ArrayList;

import chess.Board;
import chess.Tile;

/**
 * This is the view that controls the testing of the eight queens game.
 * This view supports two types of testing for eight queens. It supports random testing and
 * testing for a solution. For random testing, it will place a queens at the location (0,0)
 * and test if it can place a piece along the top most, the left most row and column and the
 * of the diagonal of the board. It will also test placing and removing other pieces on the 
 * board. For testing for a solution, it will test a completed solution of the board and check 
 * if the game has ended due to the completion of the game.
 * @author Caleb
 * <pre>
 * - Created February 20, 2010
 * </pre>
 */
public class EightQueensTestView extends TestView {
	
	public static final int RANDOM_TEST = 0;
	public static final int SOLUTION_TEST = 1;
	
	private EightQueensTestSimulatorBuilder builder;
	private int turnNumber;
	private ArrayList<EightQueensSimulatorTileInfo> tileList;
	private boolean isPieceHere;
	
	private boolean isCorrectTile;
	
	/**
	 * Creates a testing view for eight queens
	 * @param b Takes a board object
	 * <pre>
	 * Caleb Chan
	 * - Created February 20, 2010
	 * </pre>
	 */
	public EightQueensTestView(Board b){
		builder = new EightQueensTestSimulatorBuilder(b);
		tileList = new ArrayList<EightQueensSimulatorTileInfo>();
		setTestType(RANDOM_TEST);
	}
	@Override
	/**
	 * This method will choose a tile from one of the selected methods
	 * @return Returns the selected tile object
	 * <pre>
	 * Caleb Chan
	 * - Created February 20, 2010
	 * </pre>
	 */
	public Tile chooseTile() {
		turnNumber++;
		isPieceHere = tileList.get(turnNumber - 1).getTile().isPieceHere();
		return tileList.get(turnNumber - 1).getTile();
	}
	/**
	 * Sets the type of testing to be done. The list of tiles that will be selected when 
	 * choosing tiles is set when a valid type is given as a parameter. By setting the 
	 * type, it resets the testing
	 * @param type The type of testing to be done
	 * <pre>
	 * Caleb Chan
	 * - Created February 20, 2010
	 * </pre>
	 */
	public void setTestType(int type){
		if(type == RANDOM_TEST){
			tileList = builder.generateRandomTest(EightQueensTestSimulatorBuilder.SIMULATOR_DEFAULT_RANDOM);
		}else if(type == SOLUTION_TEST){
			tileList = builder.generateSolution();
		}
		turnNumber = 0;
		isCorrectTile = true;
		isPieceHere = false;
	}
	/**
	 * This will check if the move that was just made is the correct move. This check the 
	 * most recent tile that was returned by the chooseTile method
	 * @return Returns a boolean value if the eight queens game has done the right move
	 * <pre>
	 * Caleb Chan
	 * - Created February 20, 2010
	 * </pre>
	 */
	public boolean isCorrectMove(){
		isCorrectTile = moveHelper(tileList.get(turnNumber - 1).getStatus(),
				isPieceHere,tileList.get(turnNumber - 1).getTile());
		return isCorrectTile;
	}
	/**
	 * This method will get the current tile that has just been returned by the chooseTile
	 * method
	 * @return Returns the current tile
	 * <pre>
	 * Caleb Chan
	 * - Created February 20, 2010
	 * </pre>
	 */
	public Tile getCurrentTile(){
		return tileList.get(turnNumber - 1).getTile();
	}
	/**
	 * Returns the number of moves in the current test
	 * @return Returns the number of moves in the current test
	 * <pre>
	 * Caleb Chan
	 * - Created February 20, 2010
	 * </pre>
	 */
	public int getNumOfMovesInList(){
		return tileList.size();
	}
	/**
	 * Gets the string representation of the action that the move should perform
	 * @return Returns the string representation of the action
	 * <pre>
	 * Caleb Chan
	 * - Created February 20, 2010
	 * </pre>
	 */
	public String getStatus(){
		if (tileList.get(turnNumber - 1).getStatus() == EightQueensSimulatorTileInfo.PLACE_PIECE){
			return "Placed";
		}else if (tileList.get(turnNumber - 1).getStatus() == EightQueensSimulatorTileInfo.REMOVE_PIECE){
			return "Remove";
		}else if (tileList.get(turnNumber - 1).getStatus() == EightQueensSimulatorTileInfo.INVALID_PIECE){
			return "Invalid";
		}
		return "NULL";
	}
	/**
     * This is a helper method that will check if the expected value is the same as the result.
     * It will return a boolean value depending on the results
     * @param expected The expected value for the tested
     * @param hadPreviousPiece A boolean value if the there was a piece in the tile before the change
     * @param currentTile The current tile being affected
     * @return Returns a boolean on the comparison between the expected and the result
     * <pre>
     * Caleb Chan
     * - Modified February 20, 2010
     * </pre>
     */
    private boolean moveHelper(int expected,boolean hadPreviousPiece, Tile currentTile){
    	if(expected == EightQueensSimulatorTileInfo.PLACE_PIECE){
    		return currentTile.isPieceHere() == true;
    	}else if(expected == EightQueensSimulatorTileInfo.REMOVE_PIECE){
    		return currentTile.isPieceHere() == false && hadPreviousPiece;
    	}else if(expected == EightQueensSimulatorTileInfo.INVALID_PIECE){
    		return currentTile.isPieceHere() == false;
    	}
    	return false;
    }
}
